import aes from "./aes"
import rsa from "./rsa"

let requestQueue = []
let baseUrl = import.meta.env.MODE == 'prod' ? '/' + import.meta.env.VITE_CONTEXT : '/api'
let rsaPublicKey = null

const request = async (url, data, method = 'POST', headers = { 'Content-Type': 'application/json' }) => {
    // 获取加密公钥
    if (rsaPublicKey == null) {
        const pk = await fetch(`${baseUrl}/security/rsaPublicKey`).then(r => r.json())
        if (pk.code == 200) {
            rsaPublicKey = pk.data
        } else {
            ElMessage({
                showClose: true,
                message: '获取加密公钥失败',
                type: 'error',
            })
            return
        }
    }

    let aesKey = aes.generatekey()
    let encryptedData = null

    if (data) {
        const contentType = headers['Content-Type']
        let d = data
        if (contentType.indexOf('application/x-www-form-urlencoded') > -1) {
            d = ''
            for (let k in data) {
                d += k + '=' + encodeURIComponent(aes.encrypt(data[k], aesKey)) + '&'
            }
            encryptedData = d.substring(0, d.length - 1)
        } else {
            encryptedData = aes.encrypt(JSON.stringify(d), aesKey)
        }
    }
    let encryptedAesKey = rsa.encrypt(aesKey, rsaPublicKey)
    let token = localStorage.getItem('access_token')

    headers['X-Encrypt'] = encryptedAesKey

    if (token) {
        headers['Authorization'] = token
    }

    return fetch(`${baseUrl}${url}`, {
        method: method,
        headers: headers,
        body: encryptedData
    })
        .then(response => response.text())
        .then(response2 => {
            if (response2) {
                response2 = JSON.parse(aes.decrypt(response2.replace(/"/g, ''), aesKey))
                if (response2.code == 200) {
                    return response2.data
                } else if (response2.code == 401) { // access_token过期，使用refresh_token换取新的access_token
                    const refresh_token = localStorage.getItem('refresh_token')
                    if (refresh_token) {
                        request('/security/refreshAccessToken', { refreshToken: refresh_token }, 'POST', { 'Content-Type': 'application/x-www-form-urlencoded' }).then(res => {
                            if (res) {
                                localStorage.setItem('access_token', res)
                                requestQueue.forEach(rq => rq())
                                requestQueue = []
                                return res
                            } else {
                                // refresh_token失效退出
                                const u = location.href.split('#')[0]
                                localStorage.removeItem('access_token')
                                localStorage.removeItem('refresh_token')
                                location.href = u + '#/login'
                            }
                        })

                        return new Promise(resolve => {
                            requestQueue.push(() => { resolve(request(url, data, method)) })
                        })
                    }

                    // refresh_token失效退出
                    const u = location.href.split('#')[0]
                    localStorage.removeItem('access_token')
                    localStorage.removeItem('refresh_token')
                    location.href = u + '#/login'
                } else {
                    ElMessage({
                        showClose: true,
                        message: data.message,
                        type: 'error',
                    })
                }
            } else {
                return data
            }
        }).catch(err => {
            ElMessage({
                showClose: true,
                message: err,
                type: 'error',
            })
        })
}

const get = (url, data) => {
    return request(url, data, 'GET')
}

export default {
    request,
    get
}